package com.my.filter;

import java.io.IOException;
import java.net.URLDecoder;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.my.constant.Common;
import com.my.entity.Employee;
import com.my.service.EmployeeService;
import com.my.util.CookieUtil;
import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
import com.sun.org.apache.xml.internal.security.utils.Base64;

public class LoginFilter implements Filter {
	private static final Logger logger = LoggerFactory.getLogger(LoginFilter.class);

	private EmployeeService employeeService = null;
	
	public void init(FilterConfig filterConfig) throws ServletException {
		// 得到bean
		ApplicationContext appC = WebApplicationContextUtils
				.getWebApplicationContext(filterConfig.getServletContext());
		employeeService = (EmployeeService) appC.getBean("employeeService");
	}

	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		//得到request response
		HttpServletRequest req = (HttpServletRequest) request;
		HttpServletResponse res = (HttpServletResponse) response;
		//请求地址
		String uri = req.getRequestURI().toString();
		//静态文件不拦截
		if(uri.contains("static")){
			chain.doFilter(request, response);
			return;
		}
		//设置basePath
		String path = req.getContextPath();
		String basePath = req.getScheme()+"://"+req.getServerName()+":"+req.getServerPort()+path+"/";
		req.getSession().setAttribute("basePath", basePath);
		
		
		Employee employee = (Employee) req.getSession()
				.getAttribute("employee");
		//用户已经登陆
		if (null != employee) {
			//如果访问的是登陆页面，直接跳转到主页面
			if (uri.contains("to_login.do")) {
				res.sendRedirect(basePath+"index/index.do");
				return;
			} else {
				chain.doFilter(request, response);
				return ;
			}
		} else {
			//用户没有登陆，判断cookie
			Cookie[] cookies = req.getCookies();// 取cookie值，这里还有其他网站的
			if (cookies != null) {
				String cookieValue = null;
				// 下面是找到本项目的cookie
				for (int i = 0; i < cookies.length; i++) {
					if (Common.PROJECT_NAME.getValue().equals(
							cookies[i].getName())) {
						cookieValue = cookies[i].getValue();
						break;
					}
				}

				if (null != cookieValue) {
					// 先得到的CookieValue进行Base64解码
					String cookieValueAfterDecode = "";
					cookieValue = URLDecoder.decode(cookieValue, "UTF-8");
					try {
						cookieValueAfterDecode = new String(
								Base64.decode(cookieValue), "UTF-8");

					} catch (Base64DecodingException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					// 对解码后的值进行分拆,得到一个数组,如果数组长度不为3,就是非法登陆
					String cookieValues[] = cookieValueAfterDecode.split(":");
					if (cookieValues.length != 3) {
						req.getSession().setAttribute("visitUrl", req.getRequestURL());
						res.sendRedirect(basePath+"index/to_login.do");
						return;
					}
					// 判断是否在有效期内,过期就删除Cookie
					long validTimeInCookie = new Long(cookieValues[1]);
					if (validTimeInCookie < System.currentTimeMillis()) {
						// 删除Cookie
						CookieUtil.clearCookie(res);
						req.getSession().setAttribute("visitUrl", req.getRequestURL());
						res.sendRedirect(basePath+"index/to_login.do");
						return;
					}
					// 取出cookie中的用户名,并到数据库中检查这个用户名,
					String username = cookieValues[0];

					Employee emp = employeeService.queryByName(username);
					// 如果user返回不为空,就取出密码,使用用户名+密码+有效时间+
					// webSiteKey进行MD5加密。与前面设置的进行比较，看是否是同一个用户
					if (emp != null) {
						String md5ValueInCookie = cookieValues[2];
						String md5ValueFromUser = CookieUtil.getMD5(emp
								.getName()
								+ ":"
								+ emp.getPassword()
								+ ":"
								+ validTimeInCookie
								+ ":"
								+ Common.PROJECT_NAME.getValue());
						// 将结果与Cookie中的MD5码相比较,如果相同,写入Session,自动登陆成功,并继续用户请求
						if (md5ValueFromUser.equals(md5ValueInCookie)) {
							req.getSession().setAttribute("employee", emp);
							if (uri.contains("to_login.do")) {
								res.sendRedirect(basePath+"index/index.do");
								return;
							} else {
								chain.doFilter(request, response);
								return ;
							}
						}
					}

				} else {
					if (uri.contains("user/login.do") || uri.contains("to_login.do")) {
						chain.doFilter(request, response);
						return ;
					} else {
						req.getSession().setAttribute("visitUrl", req.getRequestURL());
						res.sendRedirect(basePath+"index/to_login.do");
						return ;
					}
				}

			}
		}

	}

	public void destroy() {

	}

}
